package com.junnan.adminbackend.controller;

import cn.hutool.core.io.FileTypeUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.junnan.adminbackend.config.ProcessResult;
import com.junnan.adminbackend.domain.ArkClient;
import com.volcengine.tos.TOSV2;
import com.volcengine.tos.TOSV2ClientBuilder;
import com.volcengine.tos.TosClientException;
import com.volcengine.tos.TosServerException;
import com.volcengine.tos.comm.HttpMethod;
import com.volcengine.tos.model.object.*;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import okio.BufferedSource;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import reactor.core.publisher.Flux;
import reactor.core.publisher.FluxSink;

import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;


@Slf4j
@RestController
public class ArkClientController {


    private final String API_KEY = "c4ac75ca-44e6-417e-b6dd-fedb0cab001a";

    private final String  picHost = "http://127.0.0.1:18888";

    private final String picDir = "/ark/file/";




    @PostMapping(value = "/chat", produces = org.springframework.http.MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<String> test(@RequestBody ArkClient arkClient) {

        Map<String, String> headers = new HashMap<>();
        headers.put("Authorization", "Bearer " + API_KEY);

        arkClient.setModel("doubao-seed-1-6-250615");

        arkClient.setStream(true);

        JSONObject stream_options = new JSONObject();
        stream_options.put("include_usage", true);
        arkClient.setStream_options(stream_options);



        String url = "https://ark.cn-beijing.volces.com/api/v3/chat/completions";
        OkHttpClient client = new OkHttpClient.Builder()
                .connectTimeout(30, TimeUnit.SECONDS)
                .readTimeout(30,TimeUnit.SECONDS)
                .writeTimeout(30,TimeUnit.SECONDS)
                .build();
        okhttp3.RequestBody body = okhttp3.RequestBody.create(MediaType.parse("application/json"), JSON.toJSONString(arkClient));
        Request request = new Request.Builder()
                .url(url)
                .headers(Headers.of(headers))
                .post(body)
                .build();
        log.info("调用请求:{},接口入参：{},请求头:{}", url, JSON.toJSONString(arkClient), JSON.toJSONString(headers));
        return Flux.create(fluxSink -> {
            client.newCall(request).enqueue(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                    //处理请求失败情况
                    log.error("*********流式请求人工机器人接口请求失败", e);
                    //fluxSink.error(e);
//                        fluxSink.next();
                    fluxSink.complete();
                }

                @Override
                public void onResponse(Call call, Response response) {
                    if (!response.isSuccessful()) {
                        fluxSink.error(new RuntimeException("响应失败:"+response));
                        log.error("*********流式请求人工机器人接口响应失败:{}",response);
                        fluxSink.next("请求失败");
                        return;
                    }
                    try(ResponseBody responseBody = response.body()) {
                        if (ObjectUtil.isNotEmpty(responseBody)) {
                            BufferedSource source = responseBody.source();
                            while (!source.exhausted()) {
                                String line = source.readUtf8Line();
                                if (StrUtil.isNotBlank(line)) {
                                    log.info("==============获取到的流信息结果为：{}",line);
                                    fluxSink.next(line);
                                }
                            }
                        } else {
                            log.info("~~~~~~~~流式请求人工机器人接口响应失败:ResponseBody为空");
                            fluxSink.error(new RuntimeException("请求失败:ResponseBody为空"));
                            fluxSink.next("请求失败");
                        }
                    } catch (IOException e){
                        log.error("~~~~~~~~流式请求人工机器人异常：",e);
                        //fluxSink.error(e);
//                            fluxSink.next(joinErrMsg);
                    } finally {
                        fluxSink.complete();
                    }
                }
            });
        }, FluxSink.OverflowStrategy.BUFFER);
    }


    @PostMapping("/upload")
    public ProcessResult upload(HttpServletRequest request, @RequestParam("file") MultipartFile file) throws IOException {
        String endpoint = "tos-cn-shanghai.volces.com";
        String region = "cn-shanghai";
        String accessKey = "AKLTMjdmZDRlZmU4YmQxNDZhZDlhYjkyMmJlYzMwNmFlNjc";
        String secretKey = "TkRrMk1qVmxaR1ptTnpnME5HSm1PRGhsT1dKak9UWmlORGd5WTJRMVptWQ==";
        long expires = 3600;

        String bucketName = "test-yy";
        TOSV2 tos = new TOSV2ClientBuilder().build(region, endpoint, accessKey, secretKey);

        String originalFilename = file.getOriginalFilename();
        //获取文件后缀
        //创建临时文件
        String property = System.getProperty("user.dir");
        String filePath = property + File.separator + originalFilename;
        File newFile = new File(filePath);
        file.transferTo(newFile);
        try(FileInputStream inputStream = new FileInputStream(filePath)){
            PutObjectInput putObjectInput = new PutObjectInput().setBucket(bucketName).setKey(originalFilename)
                    .setContent(inputStream).setContentLength(newFile.length());
            PutObjectOutput output = tos.putObject(putObjectInput);
            System.out.println(JSON.toJSONString(output));
            System.out.println("putObject succeed, object's etag is " + output.getEtag());
            System.out.println("putObject succeed, object's crc64 is " + output.getHashCrc64ecma());
            //删除
            PreSignedURLInput input = new PreSignedURLInput().setBucket(bucketName).setKey(originalFilename)
                    .setHttpMethod(HttpMethod.GET).setExpires(expires);
            PreSignedURLOutput outputUrl = tos.preSignedURL(input);
            log.info(JSON.toJSONString(outputUrl));
            return new ProcessResult(ProcessResult.SUCCESS, "上传成功",outputUrl.getSignedUrl());

        } catch (IOException e) {
            System.out.println("putObject read file failed");
            e.printStackTrace();
        } catch (TosClientException e) {
            // 操作失败，捕获客户端异常，一般情况是请求参数错误，此时请求并未发送
            System.out.println("putObject failed");
            System.out.println("Message: " + e.getMessage());
            if (e.getCause() != null) {
                e.getCause().printStackTrace();
            }
        } catch (TosServerException e) {
            // 操作失败，捕获服务端异常，可以获取到从服务端返回的详细错误信息
            System.out.println("putObject failed");
            System.out.println("StatusCode: " + e.getStatusCode());
            System.out.println("Code: " + e.getCode());
            System.out.println("Message: " + e.getMessage());
            System.out.println("RequestID: " + e.getRequestID());
        } catch (Throwable t) {
            // 作为兜底捕获其他异常，一般不会执行到这里
            System.out.println("putObject failed");
            System.out.println("unexpected exception, message: " + t.getMessage());
        } finally {
            newFile.delete();
        }
        return null;
    }
}
